/**
 * request 网络请求工具
 * 更详细的api文档: https://github.com/umijs/umi-request/blob/master/README_zh-CN.md
 */
import React from 'react';
import { RequestConfig } from 'umi';
import { extend, RequestOptionsInit, ResponseError } from 'umi-request';
import lodash from 'lodash';
import { notification } from 'antd';
import { formatMessage } from './utils';

// TODO: formatMessage、defaultFormatMessage不建议使用

/** 服务端返回的校验错误信息 */
export interface ValidMessage {
  /** 验证的对象名称 */
  entityName: string;
  /** 验证的字段名 */
  filed: string;
  /** 验证的字段值 */
  value: string;
  /** 验证的错误消息 */
  errorMessage: string;
  /** 验证所使用的JSR 303注解 */
  code: string;
}

export interface ValidMessageItem {
  /** 错误index位置 */
  index: string;
  /** 显示校验消息 */
  label: React.ReactNode;
  // /** 其它属性 */
  // [key: string]: any;
}

/** Http Method */
export type HttpMethod = 'get' | 'post' | 'put' | 'head' | 'delete' | 'patch' | 'options' | 'rpc';

/** 请求选项 */
export interface RequestOptions extends RequestOptionsInit {
  /** Http请求Method */
  method?: HttpMethod;
  /** 是否跳过错误处理 */
  skipErrorHandler?: boolean;
}

/** 请求对象 */
export interface Request {
  /** 请求url */
  url: string;
  /** 请求选项 */
  options: RequestOptions;
}

// /**
//  * 响应对象
//  */
// export interface Response extends Response {
// }

/** 请求错误 */
export interface ResError extends ResponseError {}

/** HTTP 状态码错误说明 */
const getErrorMessage = (status: number): string => {
  const errorMsg = {
    200: formatMessage({ id: 'common.request.error.message.200' }),
    201: formatMessage({ id: 'common.request.error.message.201' }),
    202: formatMessage({ id: 'common.request.error.message.202' }),
    204: formatMessage({ id: 'common.request.error.message.204' }),
    400: formatMessage({ id: 'common.request.error.message.400' }),
    401: formatMessage({ id: 'common.request.error.message.401' }),
    403: formatMessage({ id: 'common.request.error.message.403' }),
    404: formatMessage({ id: 'common.request.error.message.404' }),
    406: formatMessage({ id: 'common.request.error.message.406' }),
    410: formatMessage({ id: 'common.request.error.message.410' }),
    422: formatMessage({ id: 'common.request.error.message.422' }),
    500: formatMessage({ id: 'common.request.error.message.500' }),
    502: formatMessage({ id: 'common.request.error.message.502' }),
    503: formatMessage({ id: 'common.request.error.message.503' }),
    504: formatMessage({ id: 'common.request.error.message.504' }),
  };
  return errorMsg[status];
};

/** 错误处理 */
const errorHandler = async (error: ResponseError) => {
  if ((error?.request?.options as RequestOptions)?.skipErrorHandler) {
    throw error;
  }
  const { response = null } = error;
  if (response === null) throw error;
  // 成功，直接返回response
  // if (response.status >= 200 && response.status < 300) return response;
  // 失败，读取异常消息message
  let errorText;
  let json;
  try {
    json = await response.json();
    if (json && json.message) errorText = json.message;
  } catch (err) {
    errorText = undefined;
  }
  if (!errorText) {
    errorText = getErrorMessage(response.status) ?? response.statusText;
  }
  // 处理错误 - 显示
  if (response.status === 400 && json && json.validMessageList && json.validMessageList instanceof Array) {
    const validMessageList: ValidMessageItem[] = [];
    lodash.forEach(json.validMessageList, (item: ValidMessage, index) => {
      validMessageList.push({ index, label: `${item.errorMessage}(${item.filed}=${item.value})` });
    });
    notification.error({
      message: `请求参数验证失败 ${response.status}`,
      description: (
        <ol style={{ margin: 0, paddingLeft: 20 }}>
          {validMessageList.map((item) => (
            <li key={item.index}>{item.label}</li>
          ))}
        </ol>
      ),
    });
  } else {
    notification.error({ message: `请求错误 ${response.status}`, description: errorText });
  }
  // 处理错误 - 跳转
  const { status } = response;
  if (status === 401) {
    /* eslint-disable no-underscore-dangle */
    // TODO: 未登录处理
    // window.g_app._store.dispatch({ type: 'login/logout' });
  }
  // if (status === 403) {
  //   router.push('/exception/403');
  //   return;
  // }
  // if (status <= 504 && status >= 500) {
  //   router.push('/exception/500');
  //   return;
  // }
  // if (status >= 404 && status < 422) {
  //   router.push('/exception/404');
  // }
  // 继续抛出异常
  // throw error;
};

const requestConfig: RequestConfig = {
  // 自定义错误处理
  errorHandler,
  // 默认请求是否带上cookie
  credentials: 'include',
  // 全局请求头
  headers: {
    // testHeader: "test",
  },
  // 全局url前缀
  prefix: lodash.trim(API_GLOBAL_PREFIX).length > 0 ? API_GLOBAL_PREFIX : '',
};

const request = extend(requestConfig);

// 请求拦截器，更改url或选项
// request.interceptors.request.use((url, options) => {
//   return (
//     {
//       url: `${url}&interceptors=yes`,
//       options: { ...options, interceptors: true },
//     }
//   );
// });

// 响应拦截器，处理响应
// request.interceptors.response.use((response, options) => {
//   response.headers.append('interceptors', 'yes yo');
//   return response;
// });

export { getErrorMessage, requestConfig, request };
